<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <body>
    <script>
      /*
      ES6之前继承方式
        */
      (function () {
        //ES6之前继承方式
        function Person(name) {
          this.name = name;
        }
        Person.prototype.showname = function () {
          return `名字${name}`;
        };
        function Student(name, skill) {
          Person.call(this, name); //继承function Person方法
          this.skill = skill;
        }
        Student.prototype = new Person();
        let p = new Student('Strive', '继承');
        console.log(p.name); //输出Strive
        console.log(p.showname()); //输出名字
      })();
    </script>

    <script>
      /*
    绑定prototype方法
      */
      (function () {
        function Person(name, age) {
          this.name = name;
          this.age = age;
        }
        Object.assign(Person.prototype, {
          showname() {
            return `名字${this.name}`;
          },
        });
        let p = new Person('aa', 18);
        console.log(p.showname()); //输出  名字aa
      })();
    </script>

    <!-- 
class使用
constructor 方法是类的构造函数，是一个默认方法，当new后 自动执行，不写也会默认自动执行
super 子类constructor中必须使用super 因为子类没有自己的this,，而是继承父类的this，super代表这父类的构造器 相当于：父类.prototype.constructor.call(this, props)
super 这个关键字，既可以当做函数使用，也可以当做对象使用
实例解构出来后执行原型上的方法需要进行绑定this
通过get set可以执行更改/读取属性
clsss 定义的函数 读取原型需要配合static -->
    <script>
      /*
        执行顺序
         new B('b')=> B类constructor =>B类super(执行父类A)=>B类下面的
         简述 new=>constructor=>super(不断往父类执行)=>继续继承
        */
      (function () {
        class A {
          constructor(...arg) {
            console.log(arg, 'a');
            console.log(new.target.name); // new.target 指向当前正在执行的函数
            this.test = 'A';
          }
        }
        class B extends A {
          constructor(...arg) {
            console.log(arg, 'b');
            super();
            this.test2 = 'B';
          }
          bb() {
            console.log(this.test2);
          }
        }

        class C extends B {
          constructor(...arg) {
            console.log(arg, 'c');
            super(...arg); //如果写了super 需要父类也接受到B类传入的值，必须入参，否则父类(A)arg没有值
            this.test3 = 'c';
          }
          cc() {
            console.log(this.test3);
          }
        }
        const CC = new C('c');
        console.log(CC); //{test: 'A', test2: 'B', test3: 'c'}
      })();
    </script>

    <script>
      // 实例解构出来后执行原型上的方法需要进行绑定this
      (function () {
        class Person {
          constructor(name, age) {
            //构造函数 调用New自动执行
            this.name = name;
            this.showname = this.showname.bind(this);
          }
          showname() {
            return `名字${this.name}`;
          }
        }
        let p = new Person('aa', 18);
        let { showname } = p;
        console.log(showname());
      })();
    </script>

    <script>
      //    clsss 定义的函数 读取原型需要配合static
      (function () {
        class Person {
          constructor(name, age) {
            //构造函数 调用New自动执行
          }
          showname() {
            return `showname方法`;
          }
          static aaa() {
            //用person调用
            return `静态方法`;
          }
        }
        let p = new Person();
        console.log(p.showname()); //输出showname方法
        console.log(Person.aaa()); //输出静态方法方法
      })();
    </script>

    <script>
      // 通过get set可以执行更改/读取属性
      (function () {
        class Person {
          constructor(name, age) {
            //构造函数 调用New自动执行
          }
          set aaa(val) {
            //设置属性
            console.log(val); //输出123
          }
          get aaa() {
            //获取属性内容
            return `aaa属性`;
          }
        }
        let p = new Person();
        p.aaa = '123';
        console.log(p.aaa); //输出aaa属性
      })();
    </script>

    <script>
      // constructor后必须使用super super当函数使用时
      (function () {
        class Person {
          constructor(name, age) {
            //构造函数 调用New自动执行
          }
          showname() {
            return `showname方法`;
          }
          static aaa() {
            //用person调用
            return `静态方法`;
          }
        }
        let p = new Person();
        console.log(p.showname()); //输出showname方法
        console.log(Person.aaa()); //输出静态方法方法
      })();
    </script>
    <script>
      // constructor后必须使用super super当对象使用时
      (function () {
        class A {
          constructor() {
            this.x = 1;
          }
          s() {
            console.log(this.x); //2
          }
        }
        class B extends A {
          constructor() {
            super();
            this.x = 2;
          }
          m() {
            super.s(); //会去访问A的prototype但是this指向的还是本身
          }
        }
        let b = new B();
        console.log(b);
        b.m(); // 2
      })();
    </script>
  </body>
</html>
